package com.miplus.ccrm.core.service.cust;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.LabelResVo;
import com.miplus.ccrm.core.controller.vo.credit.CrdCaseResVo;
import com.miplus.ccrm.core.controller.vo.credit.DistDetailListResVo;
import com.miplus.ccrm.core.controller.vo.cust.CaseAddVo;
import com.miplus.ccrm.core.controller.vo.cust.CaseProcAddVo;
import com.miplus.ccrm.core.controller.vo.cust.CaseReqVo;
import com.miplus.ccrm.core.controller.vo.cust.CaseResVo;
import com.miplus.ccrm.core.controller.vo.file.UploadResVo;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.mapper.ConCasesMapper;
import com.miplus.ccrm.core.service.ExportService;
import com.miplus.ccrm.core.service.conf.MsgAlertsService;
import com.miplus.ccrm.core.service.crd.FiImportHistService;
import com.miplus.ccrm.core.service.file.FiApplyAttService;
import com.miplus.ccrm.core.utils.EnumFiChannel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author pc
* @description 针对表【con_cases(客户工单表)】的数据库操作Service实现
* @createDate 2024-03-20 14:33:11
*/
@Service
public class ConCasesServiceImpl extends MPJBaseServiceImpl<ConCasesMapper, ConCases>
    implements ConCasesService{

    @Resource
    private ConCaseprocessService conCaseprocessService;

    @Resource
    private MsgAlertsService msgAlertsService;

    @Resource
    private FiApplyAttService fiApplyAttService;

    @Resource
    private ExportService exportService;

    @Resource
    private FiImportHistService fiImportHistService;

    @Override
    public IPage<CaseResVo> caseList(JSysUser user,CaseReqVo paras)
    {
        String $usrid=user.getUsrid();
        String phnstar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_PHN);
        String idnostar= JUsrPerm.getPermission(user,JUsrPerm.DISSTAR_IDNO);
        boolean viewAllCase=JUsrPerm.viewAllFiCase(user);
        //数据库尽量不要使用函数，否则慢,尤其TDSQL
        //.apply("fi_hasFiCaseView({0},t.creditcaseid,t.status,t.sendtodept,t.sendtousr)>0", $usrid)
        //      log.info("getQueryWrapper:viewAllCase={},iscock={}",viewAllCase,iscock);
        boolean viewGrpFiCase = false;
        if(!viewAllCase && user.getMgrgrplist().size()>0)
            viewGrpFiCase = true;
        List<Integer> caseIds = new ArrayList<>();
        IPage<CaseResVo> pCases =  selectJoinListPage(new Page<>(paras.getPageNum(), paras.getPageSize()),
                CaseResVo.class,
                new MPJLambdaWrapper<ConCases>()
                        .leftJoin(ConCaseprocess.class,ConCaseprocess::getProcessnumber,ConCases::getLastserviceprocess)
                        .leftJoin(ConCustomer.class, "cu",ConCustomer::getCustomernumber, ConCases::getCustomernumber)
                        .leftJoin(FiCreditcases.class, FiCreditcases::getCreditcaseid,ConCases::getCollectcaseid)
//                        .selectAs("fun_getnames('CASE.STATUS',t.status)",CaseResVo::getStatusdsc)
//                        .selectAs("fun_getnames('CASE.CATEGORY',t.type1)",CaseResVo::getType1dsc)
//                        .selectAs("fun_getnames('CASE.TYPE',t.type2)",CaseResVo::getType2dsc)
//                        .selectAs("fun_getnames('CASE.TYPE',t.type3)",CaseResVo::getType3dsc)
//                        .selectAs("fun_getnames('CASE.PRIORITY' ,t.priority)",CaseResVo::getPrioritydsc)
//                        .selectAs("fun_getnames('CASE.DISTRIBUTE',t.distributemode)",CaseResVo::getDistributemodedsc)
//                        .selectAs("fun_getnames('CASE.ORIGIN',t.origin)",CaseResVo::getOrigindsc)
//                        .selectAs(String.format("fi_starSecu('%s','%s',t.contactphone,'%s')", $usrid, JUsrPerm.DISSTAR_PHN, phnstar), CaseResVo::getContactphone)
//                        .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')", $usrid, JUsrPerm.DISSTAR_IDNO, idnostar), CaseResVo::getOpenacctcertno)
//                        .selectAs("(select g.grpname from sys_grp g where g.grpid=t.sendtodept)",CaseResVo::getSendtodept)
                        .selectAll(ConCases.class)
                        .select(FiCreditcases::getMthsDay,
                                FiCreditcases::getOverdueStage,
                                FiCreditcases::getProductName,
                                FiCreditcases::getOverdueTotalamt)
                        .selectAs(ConCases::getMthsday,CaseResVo::getComplainmthsday)
                        .selectAs(ConCases::getContactname,CaseResVo::getComplainname)
                        .in(!viewAllCase && viewGrpFiCase, ConCases::getSendtodept,user.getMgrgrplist())
                        .apply(!viewAllCase && viewGrpFiCase,String.format("( t.sendtousr='%s' or t.createdby='%s')",$usrid,$usrid))
                        //.apply("fc_hasCaseView({0},t.createdby,t.distributemode,t.sendtodept,t.sendtousr)>0",$usrid)
                        .eq(JPubUtils.IsNotEmpty(paras.getCasenumber()),ConCases::getCasenumber,paras.getCasenumber())
                        .eq(JPubUtils.IsNotEmpty(paras.getCustomernumber()),ConCases::getCustomernumber,paras.getCustomernumber())
                        .likeRight(JPubUtils.IsNotEmpty(paras.getCustname()),ConCases::getContactname,paras.getCustname())
                        .between(JPubUtils.IsNotEmpty(paras.getStartdt()), ConCases::getCreateddate,JPubUtils.StringToDate(paras.getStartdt()),JPubUtils.StringToDate(paras.getEnddt()))
                        .eq(JPubUtils.IsNotEmpty(paras.getStatus()),ConCases::getStatus,paras.getStatus())
                        .eq(JPubUtils.IsNotEmpty(paras.getType1()),ConCases::getType1,paras.getType1())
                        .eq(JPubUtils.IsNotEmpty(paras.getType2()),ConCases::getType2,paras.getType2())
                        .eq(JPubUtils.IsNotEmpty(paras.getPriority()),ConCases::getPriority,paras.getPriority())
                        .eq(JPubUtils.IsNotEmpty(paras.getSendtodept()),ConCases::getSendtodept,paras.getSendtodept())
                        .eq(JPubUtils.IsNotEmpty(paras.getSendtousr()),ConCases::getSendtousr,paras.getSendtousr())
                        .eq(JPubUtils.IsNotEmpty(paras.getCreatedby()),ConCases::getCreatedby,paras.getCreatedby())
                        .eq(JPubUtils.IsNotEmpty(paras.getDistributemode()),ConCases::getDistributemode,paras.getDistributemode())
                        .eq(JPubUtils.IsNotEmpty(paras.getCollectcaseid()),ConCases::getCollectcaseid,paras.getCollectcaseid())
//                        .ge(JPubUtils.IsNotEmpty(paras.getLastprocessstartdate()),ConCaseprocess::getCreateddate,paras.getLastprocessstartdate())
//                        .le(JPubUtils.IsNotEmpty(paras.getLastprocessenddate()),ConCaseprocess::getCreateddate,paras.getLastprocessenddate())
                        .ge(JPubUtils.IsNotEmpty(paras.getLastprocessstartdate()),ConCases::getAppointdt,paras.getLastprocessstartdate())
                        .le(JPubUtils.IsNotEmpty(paras.getLastprocessenddate()),ConCases::getAppointdt,paras.getLastprocessenddate())
                        .eq(JPubUtils.IsNotEmpty(paras.getIscomplain()),ConCases::getIscomplain,paras.getIscomplain())
                        .like(JPubUtils.IsNotEmpty(paras.getIdno()),ConCustomer::getOpenacctcertno,paras.getIdno())
                        .eq(JPubUtils.IsNotEmpty(paras.getOrigin()),ConCases::getOrigin,paras.getOrigin())
                        .like(JPubUtils.IsNotEmpty(paras.getRemark()),ConCases::getRemark,paras.getRemark())
                        .like(JPubUtils.IsNotEmpty(paras.getContactphone()),ConCases::getContactphone,paras.getContactphone())
                        .exists(JPubUtils.IsNotEmpty(paras.getPhone()),String.format("select 1 from con_contact ct where ct.customernumber=t.customernumber and (ct.phone='{0}' or t.cotactphone='{0}')",paras.getPhone()))
        ).convert(x->{
            x.setUploadList(fiApplyAttService.GetApplyFile( x.getCasenumber(),"case"));
            caseIds.add(x.getCasenumber());
            return x;
        });
        if(caseIds.size()>0) {
            Map<Integer, CaseResVo>  caseList = selectJoinList(
                    CaseResVo.class,
                    new MPJLambdaWrapper<ConCases>()
                            .leftJoin(ConCaseprocess.class, ConCaseprocess::getProcessnumber, ConCases::getLastserviceprocess)
                            .leftJoin(ConCustomer.class, "cu", ConCustomer::getCustomernumber, ConCases::getCustomernumber)
                            .leftJoin(FiCreditcases.class, FiCreditcases::getCreditcaseid, ConCases::getCollectcaseid)
                            .selectAs("fun_getnames('CASE.STATUS',t.status)", CaseResVo::getStatusdsc)
                            .selectAs("fun_getnames('CASE.CATEGORY',t.type1)", CaseResVo::getType1dsc)
                            .selectAs("fun_getnames('CASE.TYPE',t.type2)", CaseResVo::getType2dsc)
                            .selectAs("fun_getnames('CASE.TYPE',t.type3)", CaseResVo::getType3dsc)
                            .selectAs("fun_getnames('CASE.PRIORITY' ,t.priority)", CaseResVo::getPrioritydsc)
                            .selectAs("fun_getnames('CASE.DISTRIBUTE',t.distributemode)", CaseResVo::getDistributemodedsc)
                            .selectAs("fun_getnames('CASE.ORIGIN',t.origin)", CaseResVo::getOrigindsc)
                            .selectAs(String.format("fi_starSecu('%s','%s',t.contactphone,'%s')", $usrid, JUsrPerm.DISSTAR_PHN, phnstar), CaseResVo::getContactphone)
                            .selectAs(String.format("fi_starSecu('%s','%s',cu.openacctcertno,'%s')", $usrid, JUsrPerm.DISSTAR_IDNO, idnostar), CaseResVo::getOpenacctcertno)
                            .selectAs("(select g.grpname from sys_grp g where g.grpid=t.sendtodept)", CaseResVo::getSendtodept)
                            .selectAs(ConCases::getCasenumber,CaseResVo::getCasenumber)
                            .in(ConCases::getCasenumber, caseIds)
            ).stream().collect(Collectors.toMap(item -> item.getCasenumber(), item -> item));
            pCases.convert(x->{
                x.setStatusdsc(caseList.get(x.getCasenumber()).getStatusdsc());
                x.setType1dsc(caseList.get(x.getCasenumber()).getType1dsc());
                x.setType2dsc(caseList.get(x.getCasenumber()).getType2dsc());
                x.setType3dsc(caseList.get(x.getCasenumber()).getType3dsc());
                x.setPrioritydsc(caseList.get(x.getCasenumber()).getPrioritydsc());
                x.setDistributemodedsc(caseList.get(x.getCasenumber()).getDistributemodedsc());
                x.setOrigindsc(caseList.get(x.getCasenumber()).getOrigindsc());
                x.setContactphone(caseList.get(x.getCasenumber()).getContactphone());
                x.setOpenacctcertno(caseList.get(x.getCasenumber()).getOpenacctcertno());
                x.setSendtodept(caseList.get(x.getCasenumber()).getSendtodept());
                return x;
            });

        }
        return pCases;
    }

    @Override
    public CaseResVo caseInfo(int caseid)
    {
        return selectJoinOne(
                CaseResVo.class,
                new MPJLambdaWrapper<ConCases>()
                        .selectAs("fun_getnames('CASE.STATUS',t.status)",CaseResVo::getStatusdsc)
                        .selectAs("fun_getnames('CASE.CATEGORY',t.type1)",CaseResVo::getType1dsc)
                        .selectAs("fun_getnames('CASE.TYPE',t.type2)",CaseResVo::getType2dsc)
                        .selectAs("fun_getnames('CASE.TYPE',t.type3)",CaseResVo::getType3dsc)
                        .selectAs("fun_getnames('CASE.PRIORITY',t.priority)",CaseResVo::getPrioritydsc)
                        .selectAs("fun_getnames('CASE.DISTRIBUTE',t.distributemode)",CaseResVo::getDistributemodedsc)
                        .selectAll(ConCases.class)
                        .eq("casenumber",caseid)
        );
    }

    //@Transactional 是回滚提交
    @Override
    @Transactional
    public CmdResVo caseInsert(String $usrid, CaseAddVo paras)
    {
        ConCases def=new ConCases();
        int ret = 0;
        BeanUtils.copyProperties(paras,def);
        String mode=paras.getDistributemode();
        if(JPubUtils.IsEmpty(mode)){
            def.setStatus("0"); //临时单或草稿单
        }
        else if(JPubUtils.IsEqual(mode,"1")){ //直接结单
            def.setStatus("10"); //已结单
        }
        else{
            def.setStatus("2"); //已派单
        }
        def.setCurrentby($usrid);
        def.setCreatedby($usrid);
        def.setCreateddate(new Date());
        def.setLastmodifiedby($usrid);
        def.setLastmodifieddate(new Date());
        def.setCasenumber(null);
        if(save(def))
            ret = 1;

        if(paras.getUploadList() != null && paras.getUploadList().size()>0 )
        {
            fiApplyAttService.AddApplyFile(def.getCasenumber(),"case",paras.getUploadList());
        }
        if(JPubUtils.IsNotEmpty(mode)){
            ConCaseprocess proc=new ConCaseprocess();
            proc.setCasenumber(def.getCasenumber());
            proc.setAction("0"); //建单
            proc.setDousr($usrid);
            proc.setCreatedby($usrid);
            proc.setCreateddate(new Date());
            conCaseprocessService.save(proc);

            proc = new ConCaseprocess();
            proc.setCasenumber(def.getCasenumber());
            proc.setDousr($usrid);
            proc.setCreatedby($usrid);
            proc.setCreateddate(new Date());
            if(JPubUtils.IsEqual(mode,"1")) {
                proc.setAction("17"); //建单
            }
            else{
                proc.setAction("1"); //派单
                proc.setSendtodept(paras.getSendtodept());
                proc.setSendtousr(paras.getSendtousr());
            }
            conCaseprocessService.save(proc);
            //保存最后的处理过程。
            def.setLastserviceprocess(proc.getProcessnumber());
            updateById(def);
            if(JPubUtils.IsEqual(mode,"2")) { //派单
                msgAlertsService.msgAlertAdd(EnumFiChannel.Case,paras.getSendtousr(),$usrid,"待处理");
            }
        }

        return new CmdResVo(ret,def.getCasenumber().toString());
    }

    @Override
    public CmdResVo caseProcessAdd(String $usrid, CaseProcAddVo paras)
    {

        if(paras.getCasenumber()==null){
            throw new ServiceException(EnumRCode.ArgFormatErr.value, EnumRCode.ArgFormatErr.name);
        }

        ConCaseprocess def=new ConCaseprocess();
        BeanUtils.copyProperties(paras,def);
        def.setCreatedby($usrid);
        def.setCreateddate(new Date());
        int ret=conCaseprocessService.getBaseMapper().insert(def);
        String action=def.getAction();

        ConCases cases=new ConCases();
        cases.setCasenumber(paras.getCasenumber());
        cases.setCurrentby($usrid);
        if(JPubUtils.IsEqual(action,"19")){ //改派
            cases.setSendtodept(paras.getSendtodept());
            cases.setSendtousr(paras.getSendtousr());
        }
        else if(JPubUtils.IsEqual(action,"17")){//结单
            cases.setStatus("10");
            cases.setClosedt(new Date());
            cases.setCloseusr($usrid);
        }
        else if(JPubUtils.IsEqual(action,"11")||JPubUtils.IsEqual(action,"18")){//取消
            cases.setStatus("12");
            cases.setClosedt(new Date());
            cases.setCloseusr($usrid);
        }
        cases.setLastmodifiedby($usrid);
        cases.setLastmodifieddate(new Date());
        //保存最后的处理过程。
        cases.setLastserviceprocess(def.getProcessnumber());
        baseMapper.updateById(cases);

        if(JPubUtils.IsEqual(action,"19")) { //改派
            msgAlertsService.msgAlertAdd(EnumFiChannel.Case,paras.getSendtousr(),$usrid,"待处理");
        }

        return new CmdResVo(ret,def.getProcessnumber().toString());
    }

    @Override
    @Transactional
    public CmdResVo caseProcessAddBatch(String $usrid, CaseProcAddVo paras) {

//        ("paras.getCasenumberList() = " + paras.getCasenumberList());

        if(paras.getCasenumberList()==null
                || paras.getCasenumberList().size()==0){
            throw new ServiceException(EnumRCode.ArgFormatErr.value, EnumRCode.ArgFormatErr.name);
        }


        int ret=0;
        try {
            for (String casenumbers : paras.getCasenumberList()) {

                Integer casenumber=Integer.valueOf(casenumbers);
                ConCaseprocess def=new ConCaseprocess();
                BeanUtils.copyProperties(paras,def);
                def.setCreatedby($usrid);
                def.setCreateddate(new Date());
                def.setCasenumber(casenumber);
                int re=conCaseprocessService.getBaseMapper().insert(def);
                if(re>0){
                    ret++;
                }
                String action=def.getAction();
                ConCases cases=new ConCases();
                cases.setCasenumber(casenumber);
                cases.setCurrentby($usrid);
                if(JPubUtils.IsEqual(action,"19")){ //改派
                    cases.setSendtodept(paras.getSendtodept());
                    cases.setSendtousr(paras.getSendtousr());
                }
                else if(JPubUtils.IsEqual(action,"17")){//结单
                    cases.setStatus("10");
                    cases.setClosedt(new Date());
                    cases.setCloseusr($usrid);
                }
                else if(JPubUtils.IsEqual(action,"11")||JPubUtils.IsEqual(action,"18")){//取消
                    cases.setStatus("12");
                    cases.setClosedt(new Date());
                    cases.setCloseusr($usrid);
                }
                cases.setLastmodifiedby($usrid);
                cases.setLastmodifieddate(new Date());
                //保存最后的处理过程。
                cases.setLastserviceprocess(def.getProcessnumber());
                baseMapper.updateById(cases);

                if(JPubUtils.IsEqual(action,"19")) { //改派
                    msgAlertsService.msgAlertAdd(EnumFiChannel.Case,paras.getSendtousr(),$usrid,"待处理");
                }

            }
        } catch (BeansException e) {
            throw new ServiceException(EnumRCode.RuntimeException.value, EnumRCode.RuntimeException.name);
        }

        return new CmdResVo(ret,paras.getCasenumberList().toString());
    }

    @Override
    public List<LabelResVo> getXbDistGrpList()
    {
        return baseMapper.getXbDistGrpList();
    }

    @Override
    public CmdResVo exportCaseList(String $usrid,JSysUser user, CaseReqVo paras, HttpServletResponse response) {

        IPage<CaseResVo> pages = caseList(user, paras);
        ArrayList arr=new ArrayList();

        String exptempid=JPubUtils.getExpTempID(paras.getExpfilename(),"历史催记列表");

        String filename=JPubUtils.getExpFileName(
                paras.getExpfilename(),exptempid
        );
        pages.convert(u->{
            HashMap map=JPubUtils.toExportMap(u);
            if(map!=null) arr.add(map);
            return u;
        });
        CmdResVo resVo=exportService.ToExcel(
                response,
                arr,
                paras.getExpidlist(),
                paras.getExpnamelist(),
                filename,
                $usrid
        );

        int okcount=resVo.getCount();
        if(okcount>0){
            fiImportHistService.AddExportHist(
                    resVo.getKeyId(),
                    $usrid,
                    exptempid,
                    filename,
                    okcount
            );
        }

        return resVo;
    }
}




